home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / clang / harderr.zip / HARDERR.C next >
Text File  |  1991-10-06  |  7KB  |  230 lines

  1. /* HARDERR.C by Bill Buckels 1991         */
  2. /* written in LARGE MODEL MICROSOFT C 5.1 */
  3.  
  4. /* This program demonstrates the use of a critical error management     */
  5. /* Technique Quite Similar to C's own System Error Routines as defined  */
  6. /* by the uniform standard in errno.h.                                  */
  7.  
  8. /* The Error Recovery and Reporting is implemented by a handler written */
  9. /* in assembly language. The reason for this is that the HARD ERRORs    */
  10. /* are handled at a fairly low level and C doesn't really offer the     */
  11. /* necessary control to implement this type of handler properly.        */
  12.  
  13. /* Bibliography : */
  14. /* The DOS Programmer's Reference 2nd Edition by Que Books provided the */
  15. /* necessary reference for both the DEVICE HEADER (page 339) and the    */
  16. /* int 24h critical error handler (page 673).                           */
  17.  
  18. /* My testing was less than thorough but all seems to work well enough   */
  19. /* and this should give folks a template and a starting point at least.  */
  20. /* I am not concerned with other compiler types since Microsoft C is the */
  21. /* Standard For Serious Developers. This will likely work with other     */
  22. /* Mixed Language Environments Like Borland but I hardly felt like       */
  23. /* Translating my work into a foreign tongue. However...                 */
  24.  
  25. /* a possible substitution of MSC functions by TURBO C functions.   */
  26. /* I am only guessing... there may be syntatical differences.       */
  27. /* also the ASM module may have different rules imposed by TASM and */
  28. /* the ISR declaration may also have semantic differences, etc.     */
  29.  
  30. #ifdef TURBO
  31.        #define _far far
  32.        #define _dos_setvect setvect
  33.        #define _dos_getvect getvect
  34.        #define _disable disable
  35.        #define _enable enable
  36.        #define _exit exit
  37. #endif
  38.  
  39. #include <stdio.h>
  40. #include <dos.h>
  41.  
  42. #ifndef TRUE
  43.      #define TRUE 1
  44. #endif
  45.  
  46. #ifndef FALSE
  47.      #define FALSE 0
  48. #endif
  49.  
  50.  
  51. /* a global structure for the hard error info.                 */
  52. /* theis structure is filled each time our int24 ISR is called */
  53. struct CRIT_ERROR{
  54.        unsigned int  HARDSTATUS;/* global status flag for Hard Errors   */
  55.        unsigned int  HERRNO;    /* global for the last error number     */
  56.        unsigned int  DEVICE_SEG;/* global for the Driver Header Segment */
  57.        unsigned int  DEVICE_OFF;/* global for the Driver Header Offset  */
  58.        unsigned char IO_STATUS; /* a DISK I/O status flag               */
  59.        };
  60.  
  61. struct CRIT_ERROR crit_error;
  62.  
  63. /* a new interrupt handler for int 24h                       */
  64. /* written in assembly language and linked to as an external */
  65. extern interrupt _far int24(void);
  66.  
  67. #ifndef MK_FP
  68.      #define MK_FP(seg,off) ((char _far *)(((long)(seg) << 16) | (off)))
  69. #endif
  70.  
  71.  
  72. char *DEVICETEST[]={
  73. "\n\tTHIS IS A TEST OF THE CRITICAL ERROR HANDLER FOR DEVICE I/O.",
  74. "\tTHE PRINTER DEVICE (PRN) IS USED FOR THIS TEST.",
  75. "\tPLEASE MAKE SURE THAT THE PRINTER IS OFF-LINE.",
  76. "\tAND PRESS THE ENTER KEY TO START THE TEST OR ESCAPE TO ABORT.",
  77. NULL};
  78.  
  79.  
  80. char *DISKTEST[]={
  81. "\n\tTHIS IS A TEST OF THE CRITICAL ERROR HANDLER FOR DISK I/O.",
  82. "\tPLEASE MAKE SURE THAT THE DRIVE DOOR FOR DRIVE A: IS LEFT OPEN",
  83. "\tAND PRESS THE ENTER KEY TO START THE TEST OR ESCAPE TO ABORT.",
  84. NULL};
  85.  
  86.  
  87.  
  88. main(int argc, char **argv)
  89. {
  90.  
  91.    FILE *fp;
  92.    int i;
  93.    char c;
  94.  
  95.    puts("\tHarderr by Bill Buckels 1991");
  96.  
  97.  
  98.    _disable();
  99.   /* replace the Hard Error Handler Vector with our own ISR. */
  100.   /* when the program terminates this vector is restored     */
  101.   /* by the system termination handler.                      */
  102.   _dos_setvect(0x24,int24);
  103.   _enable();
  104.  
  105. #define ENTERKEY '\x0d'
  106.  
  107.   /*--------------------| DISK I/O TEST |--------------------*/
  108.  
  109.   for (i=0; DISKTEST[i] != NULL; i++)puts(DISKTEST[i]);
  110.  
  111.      if((c=getch())==ENTERKEY) /* if enter is pressed do the test */
  112.      {
  113.      /* clear the previous hard error if any */
  114.      hardclear();
  115.      /* try to open an unlikely file on drive A:                  */
  116.      /* if the Drive Door is Open theis will create a HARD ERROR  */
  117.      puts("\tNow accessing disk device drive A:");
  118.      if((fp=fopen("A:\\$$$$$$$$.$$$","r"))==NULL)
  119.      {
  120.       hardperror();
  121.       }
  122.     else
  123.     {
  124.         fclose(fp);
  125.         }
  126.  
  127.    }
  128.  
  129.    if(c=='\x00')c=getch(); /* clear function keys... */
  130.  
  131.  
  132.   /*--------------------| DEVICE WRITE TEST |--------------------*/
  133.  
  134.   for (i=0; DEVICETEST[i] != NULL; i++)puts(DEVICETEST[i]);
  135.  
  136.   if((c=getch())==ENTERKEY) /* if enter is pressed do the test */
  137.   {
  138.    hardclear(); /* clear the previous error if any */
  139.    puts("\tNow accessing logical device PRN.");
  140.    if((fp=fopen("prn","w"))!=NULL)
  141.    {
  142.       while(!hardperror())fprintf(fp,"Turn The Printer Off.\n");
  143.       fclose(fp);
  144.       }
  145.    else perror("\n\tSTD ERR RE: LOGICAL DEVICE PRN");
  146.       }
  147.  
  148.    puts("\nhave a nice DOS!");
  149.    _exit(0);
  150.  
  151.  
  152. }
  153.  
  154. /* clear the Hard Error Status Flag */
  155. hardclear()
  156. {
  157.     crit_error.HARDSTATUS=FALSE;
  158. }
  159.  
  160.  
  161. /* an array of hard error messages */
  162. char *harderrors[]={
  163.  
  164. /* error code                 Meaning                        */
  165. /* (lower byte di)                                           */
  166. /* 00H */                     "Write Protect Error",
  167. /* 01H */                     "Unknown Unit",
  168. /* 02H */                     "Drive Not Ready",
  169. /* 03H */                     "Unknown Command",
  170. /* 04H */                     "Data Error (BAD CRC)",
  171. /* 05H */                     "Bad Request Structure Length",
  172. /* 06H */                     "Seek Error",
  173. /* 07H */                     "Unknown Media Type",
  174. /* 08H */                     "Sector Not Found",
  175. /* 09H */                     "Printer Out Of Paper",
  176. /* 0AH */                     "Write Fault",
  177. /* 0BH */                     "Read Fault",
  178. /* 0CH */                     "General Error"};
  179.  
  180.  
  181. /* a structure for a device header */
  182. struct DEVICE_HEADER{
  183.      unsigned long nextdriver;
  184.      unsigned int  attribute;
  185.      unsigned int  strategy_routine;
  186.      unsigned int interrupt_routine;
  187.      unsigned char device_name[9];
  188.      };
  189.  
  190.  
  191. /* if there has been a HARD error print the device error */
  192. hardperror()
  193. {
  194.     char far *device_ptr;
  195.     struct DEVICE_HEADER device_header;
  196.     int i;
  197.  
  198.   if(crit_error.HARDSTATUS!=FALSE)
  199.    {
  200.  
  201.     if(crit_error.IO_STATUS<128)
  202.     {
  203.        puts("\n\tHard Error Was Due To Disk I/O");
  204.        if(crit_error.HERRNO<0 || crit_error.HERRNO > 0x0c)
  205.              puts("\tUnknown Hard Error");
  206.       else
  207.         printf("\t%s\n",harderrors[crit_error.HERRNO]);
  208.     }
  209.     else
  210.     {
  211.       /* point to the header  of the device that has failed */
  212.       /* then print the device name to the screen.          */
  213.       device_ptr =MK_FP(crit_error.DEVICE_SEG,crit_error.DEVICE_OFF);
  214.       memcpy(&device_header.nextdriver,device_ptr,
  215.             sizeof(struct DEVICE_HEADER));
  216.       /* replace whitespace with NULLs */
  217.       for(i=0;i<8;i++)if(device_header.device_name[i] =='\x20')
  218.                          device_header.device_name[i] ='\x00';
  219.      device_header.device_name[8] ='\x00';
  220.       /* terminate ascii Z string */
  221.       puts("\n\tHard Error Was not Due To DISK I/O.");
  222.       printf("\tError was due to FAILURE of DEVICE %s.\n",
  223.              device_header.device_name);
  224.     }
  225.  }
  226.  
  227. return crit_error.HARDSTATUS;
  228.  
  229. }
  230.